import { reactive, ref } from 'vue'
import router from '@/router/index'
import { cloneDeep, isEqual, throttle } from 'lodash-es'
import useMenuStore from '@/stores/menu-store'
import { ElMessage, ElMessageBox } from 'element-plus'

export default function useForm(formData) {
    const menuStore = useMenuStore()
    // 表单ref 通用
    const formRef = ref()
    // 判断表单是否可编辑 0-新增 1-编辑 2-只读 3-审核
    const editFlag = ref(2)
    // 判断表单是否只读 editFlag=2
    const isRead = ref(false)
    // 判断表单是否审核状态 editFlag=3
    const isExamine = ref(false)
    // 加载状态
    const loadData = reactive({
        loading: false
    })
    // 判断数据是否已修改
    const updateFlag = ref(false)
    // 保存原始formData,用于判断数据是否已修改
    let initData = {}
    const setInitData = () => {
        initData = cloneDeep(formData)
    }
    // 比较数据是否修改 updateFlag=true 已修改
    const compareData = () => {
        updateFlag.value = false
        // 比较formData中的字段,否则字段为空时,会判断为未修改
        Object.keys(formData).forEach((item) => {
            const result = isEqual(formData[item], initData[item])
            if ( !result) {
                // formData 的字段值存在且与initData的不相等时,才判断为异
                if (formData[item] || formData[item] === 0 || ( !formData[item] && initData[item])) {
                    updateFlag.value = true
                }
            }
        })
    }
    /*过滤保存参数，只传输有值的或者已被修改的
      过滤规则
      *  1.为null 的不提交
      *  2.空数组的不提交
      *  3.空字符串的不提交（原本有值改空字符串的提交）
      *  4.数字0提交
      * */
    const filterFormData = () => {
        const _formData = {}
        Object.keys(formData).filter(key => (!Array.isArray(formData[key]) && !!formData[key]) || !!formData[key]?.length || formData[key] === 0 || formData[key] !== initData[key]).forEach(k => {
            _formData[k] = formData[k]
        })
        return _formData
    }
    // 重置表单
    const clearForm = () => {
        Object.keys(initData).forEach(key => {
            formData[key] = initData[key]
        })
    }
    // 返回 需要判断 数据是否已修改
    const back = () => {
        if (editFlag.value === 2) { // 只读 直接退出
            menuStore.handleRemoveTab(router.currentRoute.value.fullPath)
            return
        }
        compareData()
        if (updateFlag.value) {
            ElMessageBox.confirm(
                '内容尚未保存,是否确认退出本页?',
                {
                    confirmButtonText: '继续退出',
                    cancelButtonText: '取消'
                }).then(() => {
                menuStore.handleRemoveTab(router.currentRoute.value.fullPath)
            }).catch()
        } else {
            menuStore.handleRemoveTab(router.currentRoute.value.fullPath)
        }
    }
    // 通过menuStore.handleFormRouter中缓存的id获取表单数据,一般用于跳转的form
    const getFormDataById = async (apiMethod) => {
        // 先判断
        const _params = JSON.parse(window.sessionStorage.getItem(router.currentRoute.value.name + 'Params'))
        // 不存在id时,为新增
        if ( !_params?.id) {
            editFlag.value = 0
            setInitData()
            return
        }
        loadData.loading = true
        try {
            const res = await apiMethod(_params.id)
            Object.keys(formData).forEach(key => {
                formData[key] = res.data[key]
            })
            editFlag.value = _params?.editFlag
            // 设置只读
            if (_params?.editFlag === 2) isRead.value = true
            setInitData()
        } catch (e) {
        } finally {
            loadData.loading = false
        }
    }
    /* 保存
    *  @params {function} saveMethod 发送formData的api
    *  @params {string} name 表单名，用于给用户显示正在修改的数据名（如：角色、菜单）
    *  @params {number} successMsg 保存成功后的提示，可自定义，留空时自动使用默认
   */
    const saveForm = throttle((saveMethod, name = '', successMsg = null) => {
        // 比较数据是否修改过 true= 修改过 方法来自 use-form.js
        compareData()
        // updateFlag=false 表单未被修改，参数来自  use-form.js
        if ( !updateFlag.value) {
            ElMessage.error({message: '表单未被修改!'})
            return false
        }
        let msg = ''
        switch (editFlag.value) {
            case 0:
                msg = '新增'
                break
            case 1:
                msg = '修改'
                break
            case 2:
                msg = '查看'
                break
            case 3:
                msg = '审批'
                break
        }
        formRef.value.validate(valid => {
            if (valid) {
                loadData.loading = true
                ElMessageBox.confirm(`此操作将${msg}${name}, 是否继续?`, '保存提示').then(async () => {
                    try {
                        // filterFormData 过滤保存参数，只传输有值的或者已被修改的 方法来自 use-form.js
                        const _formData = await filterFormData?.()
                        await saveMethod?.(_formData)
                        const _successMsg = successMsg ?? `${msg}${name}成功！请刷新表格。`
                        ElMessage.success({
                            message: _successMsg
                        })
                        // 保存成功，退出
                        menuStore.handleRemoveTab(router.currentRoute.value.fullPath)
                    } catch (e) {
                    } finally {
                        loadData.loading = false
                    }
                }).catch(() => {
                    // 点击取消后 关闭loading
                    loadData.loading = false
                })
            }
        })
    }, 1000)
    return {
        menuStore,
        isRead,
        isExamine,
        compareData,
        setInitData,
        updateFlag,
        formRef,
        loadData,
        clearForm,
        back,
        editFlag,
        router,
        saveForm,
        getFormDataById,
        filterFormData
    }
}
